package jpa.impls;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import jpa.daos.UserDao;
import jpa.entities.User;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository("UserDao")
@Transactional(readOnly = true)
//@Controller
public class UserDaoImpl implements UserDao {
	@PersistenceContext
	private EntityManager entityManager;

	/* (non-Javadoc)
	 * @see daos.UserDao#insertUser(entities.User)
	 */
	@Override
	@Transactional
	public Long insertUser(User user) {		
		try {
			System.out.println("........... Persisting Object  " + user.getUsername() + "  .............."); 
			user = userExists(user);
			entityManager.persist(user);
			entityManager.flush();
		} catch (Exception e) {
			e.printStackTrace();		
		}
		return user.getId();
	}

	/* (non-Javadoc)
	 * @see daos.UserDao#findAllUsers()
	 */
	@Override
	public List<User> findAllUsers() {
		TypedQuery<User> query = entityManager.createQuery("SELECT g FROM User g ORDER BY g.id", User.class);
		return query.getResultList();
	}
	
/*	@SuppressWarnings("unchecked")
	public List<User> getAll() {		
		Query query = entityManager.createNamedQuery("User.findAll");
		List<User> users = null;
		users = query.getResultList();
		return users;
	}
	
	// Retrieves all Users differently
	public List<User> getAllUsers() {
		CriteriaBuilder builder = entityManager.getCriteriaBuilder();
		CriteriaQuery<User> query = builder.createQuery(User.class);
		Root<User> root = query.from(User.class);
		query.select(root);		

		return entityManager.createQuery(query).getResultList();
	}*/

	@Override
	public void delete(User user) {
		// check that it exists in the DB
		user = entityManager.getReference(User.class, user.getId());
		
		if (user != null) {					
			entityManager.remove(user);
			entityManager.flush();
		}
	}

	@Override
	public User findById(Long id) {
		return entityManager.find(User.class, id);
	}

	@Override
	public User findByUsername(String username) {
		User user = null;
		try {
			TypedQuery<User> query = entityManager.createNamedQuery("User.getByUsername", User.class)
					.setParameter("username", username);
			
			List<User> users = query.getResultList();
			
			user = (!users.isEmpty()) ? users.get(0) : null;
		} catch(Exception e) {
			e.printStackTrace();
		}
		return user;
	}
	
	@Override
	public User userExists(User user) {			
		User u = findByUsername(user.getUsername());
		user =  u != null ? u : user; 
		
		return user;
	}
	
	@Override
	public boolean usernameExists(String username) {		
		Query query = entityManager.createNamedQuery("User.exists")
				.setParameter("username", username);			
		int count = ((Number) query.getSingleResult()).intValue();
		
		return (count > 0) ? true : false;
	}

	@Override
	public Long getIdByUsername(String username) {		
		return getUserByUsername(username).getId();
	}
	

	@Override
	public User getUserByUsername(String username) {
		User u = null;
		if (usernameExists(username)) {			
			u = findByUsername(username);			
		}				
		
		return u;
	}

	@Override
	public User findUser(User user) {
		user = findByUsername(user.getUsername());
		return user;
	}

}
